//
// See the file COPYING for redistribution information.
//

#include <iostream>
#include <cstring>
#include <Naipax.hpp>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

using namespace std;
using namespace Naipax;

int main() {
    cerr << "Test for the Ares module" << endl;

    try {
        static const uint32_t sNameListSize = 100;
        char NameList[sNameListSize][64] = {
            "google.com", "kimo.com", "www.taipei.gov.tw",
            "www.yahoo.com", "www.pchome.com.tw", "del.icio.us",
            "digg.com", "ford.com", "toyota.com",
            "apple.com", "iphone.com", "baidu.com", "sohu.com",
            "sina.com", "qoopi.com", "trendmicro.com", "microsoft.com",
            "www.stanford.edu", "mit.edu",
            "google.com", "kimo.com", "www.taipei.gov.tw",
            "www.yahoo.com", "www.pchome.com.tw", "del.icio.us",
            "digg.com", "ford.com", "toyota.com",
            "apple.com", "iphone.com", "baidu.com", "sohu.com",
            "sina.com", "qoopi.com", "trendmicro.com", "microsoft.com",
            "www.stanford.edu", "mit.edu",
            "www.myextralife.com", "searchengineland.com",
            "www.youbuynow.com", "odeo.com", "perl.org",
            "mac.org", "php.net", "perl.com", "perlmonks.org",
            "yaml.org", "json.org", "cpan.org",
            "\0"
        };

        Ares DnResolver(20);
        for (uint32_t i = 0;
             i < sNameListSize && NameList[i][0] != '\0';) {
            cout << "Submitting " << i << " => " << NameList[i] << "...";

            bool IsSubmitted = true;
            AresData DnData(NameList[i], strlen(NameList[i]));
            
            if (DnResolver.Submit(DnData) != 0) {
                IsSubmitted = false;
                cout << endl;
            }
            else {
                cout << "Done" << endl;
            }
            if (DnResolver.HasUnresolved() == true) {
                vector<AresData> DnDataVector;
                if (DnResolver.HasResult(DnDataVector) == true) {
                    cout << "----" << endl;
                    for (vector<AresData>::iterator
                             DataIter = DnDataVector.begin();
                         DataIter != DnDataVector.end(); ++DataIter) {
                        if (DataIter->mIsIpV6 == false) {
                            cout << DataIter->mHostname << " "
                                 << inet_ntoa(DataIter->mIpV4Addr) << " "
                                 << DataIter->mTtl << endl;
                        }
                    }
                }
            }
            if (IsSubmitted == true) {
                ++i;
            }
        }

        while (DnResolver.HasUnresolved() == true) {
            vector<AresData> DnDataVector;
            if (DnResolver.HasResult(DnDataVector) == true) {
                cout << "----" << endl;
                for (vector<AresData>::iterator
                         DataIter = DnDataVector.begin();
                     DataIter != DnDataVector.end(); ++DataIter) {
                    if (DataIter->mIsIpV6 == false) {
                        cout << DataIter->mHostname << " "
                             << inet_ntoa(DataIter->mIpV4Addr) << " "
                             << DataIter->mTtl << endl;
                    }
                }
            }
        }
        DnResolver.Cancel();
    }
    catch (Naipax::Error &E) {
        NAIPAX_PERROR(E.What());
        return -1;
    }
    return 0;
}
